import { Window } from "@/core/window/window"
import type { WindowContent } from "@/core/window/window-content"
import type WindowProps from "@/core/window/window-props"
import type { Application } from "@/core/application/application"
import { WindowActiveProcessor } from "@/core/window/window-active-processor"
import * as _ from "lodash"

export class WindowContext {
  readonly application: Application
  readonly windows: Map<string, Window>

  readonly activeProcessor: WindowActiveProcessor

  constructor(application: Application) {
    this.application = application
    this.windows = new Map<string, Window>()
    this.activeProcessor = new WindowActiveProcessor(this)
  }

  size() {
    return this.windows.size
  }

  createWindow(content: string | WindowContent, props?: WindowProps) {
    let realContent: WindowContent | undefined
    if (typeof content === "string") {
      realContent = this.application.info.content.windowContents.get(content)
      if (!realContent) {
        throw new Error("未找到要加载的窗口内容" + content)
      }
    } else {
      realContent = content
    }
    const window = new Window(undefined, this.application, realContent, props, undefined)
    this.windows.set(window.id, window)
  }

  closeWindow(id: string) {
    if (this.windows.size === 1 && this.windows.has(id)) {
      this.application.close()
      return
    }
    this.windows.delete(id)
  }

  isHidden() {
    for (const w of this.windows.values()) {
      if (w.getStatus() !== "minimize") {
        return false
      }
    }
    return true
  }

  hide() {
    for (const w of this.windows.values()) {
      if (w.getStatus() === "minimize") {
        continue
      }
      w.switchMinimize()
    }
  }

  show() {
    for (const w of this.windows.values()) {
      if (w.getStatus() !== "minimize") {
        continue
      }
      w.switchMinimize()
    }
  }

  close() {
    this.windows.clear()
  }

  fromState(obj: any) {
    if (!obj) {
      return
    }
    this.activeProcessor.fromState(obj.activeProcessor)
    _.forEach(obj.windows, (value: any, key: string) => {
      const window = Window.formState(value, this.application)
      if (window) {
        this.windows.set(key, window)
      }
    })
  }

  toState(): any {
    const obj: any = {}
    obj.activeProcessor = this.activeProcessor.toState()
    obj.windows = this.toState4Windows()
    return obj
  }

  private toState4Windows() {
    const obj: any = {}
    for (const [key, value] of this.windows) {
      obj[key] = value.toState()
    }
    return obj
  }
}
